#include "SocketIO.h"

SocketIO::SocketIO(int fd)
    : _clt{fd}
{
}

int SocketIO::writen(const char *str, size_t len)
{
    int left = len;
    const char *ptr = str;
    int ret{};
    while (left > 0)
    {
        ret = ::write(_clt.fd(), ptr, left);
        if (-1 == ret && errno == EINTR)
        {
            continue;
        }
        else if (-1 == ret)
        {
            perror("writen");
            exit(-1);
        }
        left -= ret;
        ptr += ret;
    }
    return len - left;
}

int SocketIO::readLine(char *str, size_t len)
{
    // std::cout << "---------------------" << std::endl;
    int left = len;
    char *ptr = str;
    int ret{};
    while (left > 0)
    {
        ret = ::recv(_clt.fd(), ptr, left, MSG_PEEK);
        if (-1 == ret && errno == EINTR)
        {
            continue;
        }
        else if (-1 == ret)
        {
            perror("readLine");
            exit(-1);
        }
        else
        {
            for (size_t idx{}; idx < ret; idx++)
            {
                if (ptr[idx] == '\n')
                {
                    // 边界问题：必须要读完内核数据中的所有数据，否则会一直触发读事件
                    readn(ptr, idx + 1);
                    ptr += idx + 1;
                    left -= idx;
                    *ptr = '\0';
                    return len - left;
                }
            }

            readn(ptr, ret);
            ptr += ret;
            left -= ret;
        }
    }
    *ptr = '\0';
}

int SocketIO::readn(char *str, size_t len)
{
    int left = len;
    char *ptr = str;
    int ret{};
    while (left > 0)
    {
        ret = ::read(_clt.fd(), ptr, left);
        if (-1 == ret && errno == EINTR)
        {
            continue;
        }
        else if (-1 == ret)
        {
            perror("readn");
            exit(-1);
        }
        else if (ret == 0)
        {
            return len - left;
        }
        else
        {
            ptr += ret;
            left -= ret;
        }
    }
    return len - left;
}